From dc21926aff31c26c2c291fe02ecf7c31e956a921 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Sat, 23 Jul 2011 09:43:47 +0100 Subject: [PATCH] hvmloader: New functions mem_hole_alloc() and mem_hole_populate_ram(). These can be used by BIOS-specific handlers to set up memory regions as required by their firmware payload. Use mem_hole_alloc() to allocate properly reserved space for the shared-info-page mapping. The old location conflicts with space required for the OVMF BIOS (support for which is work in progress). Signed-off-by: Keir Fraser --- tools/firmware/hvmloader/util.c | 50 +++++++++++++++++++++------------ tools/firmware/hvmloader/util.h | 7 +++++ 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/tools/firmware/hvmloader/util.c b/tools/firmware/hvmloader/util.c index 1180cbc566..0801fb6aac 100644 --- a/tools/firmware/hvmloader/util.c +++ b/tools/firmware/hvmloader/util.c @@ -303,29 +303,14 @@ uuid_to_string(char *dest, uint8_t *uuid) *p = '\0'; } -void *mem_alloc(uint32_t size, uint32_t align) +void mem_hole_populate_ram(xen_pfn_t mfn, uint32_t nr_mfns) { - static uint32_t reserve = RESERVED_MEMBASE - 1; static int over_allocated; struct xen_add_to_physmap xatp; struct xen_memory_reservation xmr; - xen_pfn_t mfn; - uint32_t s, e; - - /* Align to at least 16 bytes. */ - if ( align < 16 ) - align = 16; - s = (reserve + align) & ~(align - 1); - e = s + size - 1; - - BUG_ON((e < s) || (e >> PAGE_SHIFT) >= hvm_info->reserved_mem_pgstart); - - while ( (reserve >> PAGE_SHIFT) != (e >> PAGE_SHIFT) ) + for ( ; nr_mfns-- != 0; mfn++ ) { - reserve += PAGE_SIZE; - mfn = reserve >> PAGE_SHIFT; - /* Try to allocate a brand new page in the reserved area. */ if ( !over_allocated ) { @@ -356,6 +341,35 @@ void *mem_alloc(uint32_t size, uint32_t align) if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 ) BUG(); } +} + +static uint32_t reserve = RESERVED_MEMBASE - 1; + +xen_pfn_t mem_hole_alloc(uint32_t nr_mfns) +{ + hvm_info->reserved_mem_pgstart -= nr_mfns; + BUG_ON(hvm_info->reserved_mem_pgstart <= (reserve >> PAGE_SHIFT)); + return hvm_info->reserved_mem_pgstart; +} + +void *mem_alloc(uint32_t size, uint32_t align) +{ + uint32_t s, e; + + /* Align to at least 16 bytes. */ + if ( align < 16 ) + align = 16; + + s = (reserve + align) & ~(align - 1); + e = s + size - 1; + + BUG_ON((e < s) || (e >> PAGE_SHIFT) >= hvm_info->reserved_mem_pgstart); + + while ( (reserve >> PAGE_SHIFT) != (e >> PAGE_SHIFT) ) + { + reserve += PAGE_SIZE; + mem_hole_populate_ram(reserve >> PAGE_SHIFT, 1); + } reserve = e; @@ -635,7 +649,7 @@ struct shared_info *get_shared_info(void) xatp.domid = DOMID_SELF; xatp.space = XENMAPSPACE_shared_info; xatp.idx = 0; - xatp.gpfn = 0xfffffu; + xatp.gpfn = mem_hole_alloc(1); shared_info = (struct shared_info *)(xatp.gpfn << PAGE_SHIFT); if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 ) BUG(); diff --git a/tools/firmware/hvmloader/util.h b/tools/firmware/hvmloader/util.h index 5d0798c47f..3c253ea64b 100644 --- a/tools/firmware/hvmloader/util.h +++ b/tools/firmware/hvmloader/util.h @@ -3,6 +3,7 @@ #include #include +#include #include #define __STR(...) #__VA_ARGS__ @@ -164,6 +165,12 @@ void uuid_to_string(char *dest, uint8_t *uuid); int printf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); int vprintf(const char *fmt, va_list ap); +/* Populate specified memory hole with RAM. */ +void mem_hole_populate_ram(xen_pfn_t mfn, uint32_t nr_mfns); + +/* Allocate a memory hole below 4GB. */ +xen_pfn_t mem_hole_alloc(uint32_t nr_mfns); + /* Allocate memory in a reserved region below 4GB. */ void *mem_alloc(uint32_t size, uint32_t align); #define virt_to_phys(v) ((unsigned long)(v)) -- 2.30.2